package com.arron.juc;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Classname LockDemo
 * @Description TODO
 * @Date 2020/8/21 0:53
 * @Created by 刘
 */
public class LockDemo {

    Lock lock = new ReentrantLock();

    public synchronized void add(){
        //对于同一个线程，不用在获取锁，自动获取锁
        System.out.println(Thread.currentThread().getName()+"\t invoke add()");
        dec();
    }
    public synchronized void dec(){
        System.out.println(Thread.currentThread().getName()+"\t invoke dec()");
    }


    public void a(){
        lock.lock();
//        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+"\t invoke a()");
            b();
        }finally {
//            lock.unlock();
            lock.unlock();
        }
    }
    public void b(){
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+"\t 获取到锁");
            try {
                Thread.sleep(100000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"\t invoke b()");
        }finally {
            lock.unlock();
        }
    }


    public static void main(String[] args) {

        LockDemo lockDemo = new LockDemo();

//        new Thread(()->{
//            lockDemo.add();
//        },"A").start();
//        new Thread(()->{
//            lockDemo.add();
//        },"B").start();

//        try {
//            TimeUnit.SECONDS.sleep(1);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        CyclicBarrier cyclicBarrier= new CyclicBarrier(2);
        new Thread(()->{
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            lockDemo.a();
        },"C").start();
        new Thread(()->{
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            lockDemo.b();
        },"D").start();


    }
}
